Stackdriver Logging から BigQuery で集計する
既に Sink が設定してあるログ構造を変えたい場合
どうなるのか
フィールド追加したら
しれっと BQ テーブル上でも増えるとうれしい
エラーにはならないが次の日からテーブル定義が更新されるとうれしい
UI 的には、分割テーブルは日別にスキーマがありそう
横断したクエリを投げた時エラーになる?
フィールドの型が変わったら
エラーになりそうだが、どうフィールドバックされる?
全然別の構造になったら
CLI で取得できるログを import する
ローカルアップロードよりは GCP 内で完結するほうが速いはず
ちょっとしたデータなら CloudShell でよい?
ログを csv で書き出す
$ gcloud logging read 'logName="..." AND ...' --format='csv(jsonPayload.location, jsonPayload.ok, jsonPayload.documents_size, jsonPayload.time)' > log.csv
--format='csv(...)' で必要なフィールドを取り出し csv にする
C-c などで途中で打ち切ったら末尾の行を手で消せばよい
リダイレクトせずに--limit=10 とかで動作確認しつつ
BigQuery へロードする
$ bq load --source_format=csv --autodetect mydataset.mytable ./log.csv
これで BigQuery で検索できる
大量のログを取り出したり変換したりは時間かかるので、先に Cloud Logging 側で sink を作ってないが保存期間内の過去データをどうしても BigQuery に入れたい場合の避難策 以下は JSON 版、キーを先に明示して csv で出すほうが楽
---.icon
ログを json で書き出す
$ gcloud logging read 'logName="..." AND timestamp >= ... ANDD timestamp < ...' --format=json > log.json
ここで --format=json(jsonPayload) でフィルタしてもよい
jsonPayload だけ取り出す & ndjson にする
$ cat log.json | jq -c '.[].jsonPayload' > log.ndjson.json
--format=json だと全体が 1 つの array になっているけど BigQuery の JSON アップロードは NDJSON を期待する
どうせ使うのは jsonPayload
BigQuery へインポート
code:bq_load
bq load \
--source_format=NEWLINE_DELIMITED_JSON \
--autodetect \
my_dataset.my_table ./log.json
json で出力すると、全体が1つの array になるので ndjson への変換がめんどい
途中で打ち切ったときもちょっと整形しないといけない
csv で出すと良さそう
ネストするとだめなので、以下のようにキーを指定して1次元にできると csv 出力できる
$ gcloud logging read 'logName=(...)' format='csv(jsonPayload.ok,jsonPayload.location)'
事前に使うキーが分かってないといけない
ログを sink するときはどういう処理をしてるんだろ? もっと賢い書き方がありそう